#pragma once

#include <U8g2lib.h>

#include "./u8g2_font_menu_chs.hpp"


extern U8G2 u8g2;


namespace beef {
    constexpr auto BIG_TEXT_FONT = u8g2_font_spleen8x16_mr;
    constexpr auto SMALL_TEXT_FONT = u8g2_font_spleen5x8_mr;
    constexpr auto CHS_FONT = u8g2_font_menu_chs;
    constexpr auto MENU_FONT = u8g2_font_menu_chs;


    using PointType = uint8_t;
    using FontType = const uint8_t*;


    inline void init_oled() {
        u8g2.begin();
        u8g2.enableUTF8Print();
        u8g2.setFontRefHeightAll();
    }


    inline void oled_clear_box(PointType x, PointType y, PointType w, PointType h) {
        u8g2.setDrawColor(0);  // 反色
        u8g2.drawBox(x, y, w, h);
        u8g2.setDrawColor(1);
    }


    inline void oled_draw_frame(PointType x, PointType y, PointType w, PointType h, bool padding = true) {
        // 绘制边框, 如果padding 为true，则实际显示宽度比w - 2px，高度比h - 2px
        if (padding) {
            oled_clear_box(x, y, w, h);  // 先清空整个占用区域
            w -= 2;
            h -= 2;
            x += 1;
            y += 1;
        }

        u8g2.drawFrame(x, y, w, h);
    }


    struct FramePlacing {
        PointType frame_x = 0;  // 编辑界面边框左上角顶点坐标
        PointType frame_y = 0;
        PointType frame_w = 0;  // 编辑界面边框宽度，边框线的实际宽度是2px，内侧是1px 宽度的实线，外侧附加1px 宽度的clear 区域
        PointType frame_h = 0;  // 编辑界面边框高度

        PointType title_offset_x = 0;  // 相比基准位置的水平偏移
        PointType title_offset_y = 0;  // 相比基准位置的垂直偏移

        PointType extra_headroom = 0;  // 额外的标题头部空间，用于调整标题位置
    };


    inline void oled_draw_frame_with_title(const FramePlacing& placing, const char* title) {
        oled_draw_frame(placing.frame_x, placing.frame_y, placing.frame_w, placing.frame_h);
        auto title_x = placing.frame_x + placing.title_offset_x + 4;
        auto title_y = placing.frame_y + placing.title_offset_y + 3;
        auto font_height = u8g2.getAscent();
        auto clear_x = title_x - 1;
        auto clear_y = title_y - font_height - placing.extra_headroom;
        auto clear_w = u8g2.getUTF8Width(title) + 2;
        auto clear_h = font_height + u8g2.getDescent() + 4 + placing.extra_headroom;
        oled_clear_box(clear_x, clear_y, clear_w, clear_h);
        u8g2.drawUTF8(title_x, title_y, title);
    }


    inline void oled_draw_frame_with_title(const FramePlacing& placing, const char* title, FontType font) {
        u8g2.setFont(font);
        oled_draw_frame_with_title(placing, title);
    }


    inline void refresh_screen_when(bool condition) {
        if (condition) {
            u8g2.sendBuffer();
        }
    }


    inline void refresh_screen_when(bool c1, bool c2) {
        refresh_screen_when(c1 || c2);
    }


    inline void refresh_screen_when(bool c1, bool c2, bool c3) {
        refresh_screen_when(c1 || c2 || c3);
    }


    inline void refresh_screen_when(bool c1, bool c2, bool c3, bool c4) {
        refresh_screen_when(c1 || c2 || c3 || c4);
    }


    inline void refresh_screen_when(bool c1, bool c2, bool c3, bool c4, bool c5) {
        refresh_screen_when(c1 || c2 || c3 || c4 || c5);
    }
}  // namespace beef